package com.tarry.socket.group.chat;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

@Slf4j
public class GroupChatClient {
    private String ip;
    private int port;
    private Selector selector;
    private SocketChannel socketChannel;
    private String userName;

    public GroupChatClient(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    public void start() {
        try {
            this.selector = Selector.open();
            this.socketChannel = SocketChannel.open(new InetSocketAddress(this.ip, this.port));
            this.socketChannel.configureBlocking(false);
            this.socketChannel.register(this.selector, SelectionKey.OP_READ);
            this.userName = this.socketChannel.getLocalAddress().toString();
            log.info("{} started ~~~~",this.userName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void readMsg() {
        try {
            // 设置超时时间
            this.selector.select(2000);
            Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                // 读取事件
                if (selectionKey.isReadable()) {
                    SocketChannel channel = (SocketChannel) selectionKey.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    byteBuffer.clear();
                    int count = channel.read(byteBuffer);
                    byteBuffer.flip();
                    if (count > 0) {
                        String msg = new String(byteBuffer.array(), 0, count, StandardCharsets.UTF_8);
                        log.info("get msg from {} : {}",channel.getRemoteAddress(),msg);
                    }
                }
                // 移除监听，防止重复操作
                iterator.remove();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMsg(String msg) {
        try {
            log.info("{} send msg : {}", this.userName, msg);
            this.socketChannel.write(ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        GroupChatClient groupChatClient = new GroupChatClient("127.0.0.1", 6667);
        groupChatClient.start();
        // 等待接收服务端消息
        new Thread( () -> {
            while (true) {
                groupChatClient.readMsg();
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Scanner scanner = new Scanner(System.in);

        // 发送消息
        while (scanner.hasNextLine()) {
            String msg = scanner.nextLine();
            groupChatClient.sendMsg(msg);
        }
    }

}
